 package com.hp.bon.sgw.wh.channel.handler;

import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.ocs.diameter.message.AVP;
import com.hp.ocs.diameter.message.AVP_Grouped;
import com.hp.ocs.diameter.message.AVP_Integer32;
import com.hp.ocs.diameter.message.AVP_Time;
import com.hp.ocs.diameter.message.AVP_UTF8String;
import com.hp.ocs.diameter.message.AVP_Unsigned32;
import com.hp.ocs.diameter.message.InvalidAVPLengthException;
import com.hp.ocs.diameter.message.Message;

/**  
 * @ClassName: ZWNLFXHandle   
 * @Description: 帐务能力中心返销接口
 * @author:	zhoumengyi  
 * @date:2019年7月5日 上午10:49:30
 */
public class ZWNLFXHandle implements IAsynCallHandler{
	private static final Logger _log = LoggerFactory.getLogger(ZWNLFXHandle.class);
	
	private PrintStream printStream;
	
	public ZWNLFXHandle(PrintStream printStream)
	{
		this.printStream = printStream;
	}
	
	@Override
	public int getProtocolType() {
		return 0;
	}

	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;
		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}
		if (response == null) {
			int _retcodeTmp = callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode();
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(),_retcodeTmp, callParam.getResultMsg());
			callParam.setServiceResultCode(_retcodeTmp);//11203
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				_log.warn("unknown response type:" + callParam.getResponse().getClass().getName());
			}
		}
		try {
			String respXML = convertResponseString((Message)response,callParam.getServiceResultCode());
			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();
			callParam.setResponse(ack);
			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库
				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}
			TaskManager.taskProcess(callParam);
			_log.info("http response(cfq) " + respXML);
		} catch (UnsupportedEncodingException e) {
			_log.info("convertResponseString UnsupportedEncodingException error,msg=" + e.getMessage());
		} catch (IOException e) {
			_log.info("convertResponseString IOException,msg=" + e.getMessage());
		}
	}


	/**
	 * 从Message中解析出需要的数据，并拼接成json字符串
	 * @param answer
	 * @param serviceResultCode
	 * @return
	 */
	private String convertResponseString(Message answer, int serviceResultCode) {
		_log.info("HBCFQHandle serviceResultCode = {}",serviceResultCode);
		String response = "";	    	
		Map<String,String> data = new HashMap<String, String>();
		Map<String,String> map = getAvpsFromMessage(answer);
		if(map == null){
			// 解析下游返回数据出错
			data.put("resultCode", "-1");
			data.put("resultMsg", "查询失败");
		}else if(serviceResultCode != 0){
			// 如果返回了错误码，则将错误信息转给用户
			data.put("resultCode", serviceResultCode + "");
			data.put("resultMsg", map.get("Para_Field_Result") == null ? "" : map.get("Para_Field_Result"));
		}else{
			data.put("resultCode", "0");
			data.put("resultMsg", "SUCCESS");
			data.put("newPaymentId", map.get("Reverse_Serial_Nbr"));
		}
		Gson gson = new Gson();
		response = gson.toJson(data);
		return response;
	}
	
	
	/**
	 * 从返回信息中解析AVP信息
	 * @param answer
	 * @return
	 */
	public Map<String, String> getAvpsFromMessage(Message answer){
		Map<String, String> map = new HashMap<String, String>();
	    AVP avp = answer.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION,Constants.DIAMETER_VENDOR_3GPP);
	    AVP_Grouped avpServiceInfomation;
		try {
			avpServiceInfomation = new AVP_Grouped(avp);
			// 业务级的结果代码
		    AVP Result = avpServiceInfomation.find(20631,Constants.DIAMETER_VENDOR_CT);
		    if (Result != null){
		    	map.put("Result", String.valueOf(new AVP_Unsigned32(Result).queryValue()));
		    }
		    // Para_Field_Result节点
		    AVP Para_Field_Result = avpServiceInfomation.find(80407,Constants.DIAMETER_VENDOR_CT);
			if (Para_Field_Result != null){
				map.put("Para_Field_Result", new AVP_UTF8String(Para_Field_Result).queryValue());
			}
		    
		    AVP Reverse_Information = avpServiceInfomation.find(80171,Constants.DIAMETER_VENDOR_CT);
		    if(Reverse_Information != null){
		    	AVP_Grouped avpReverseInformation = new AVP_Grouped(Reverse_Information);
		    	// 返销金额
		    	AVP Reverse_Amount = avpReverseInformation.find(80153,Constants.DIAMETER_VENDOR_CT);
		    	if (Reverse_Amount != null){
		    		map.put("Reverse_Amount", String.valueOf(new AVP_Integer32(Reverse_Amount).queryValue()));
		    	}
		    	// 返销流水
		    	AVP Reverse_Serial_Nbr = avpReverseInformation.find(80155,Constants.DIAMETER_VENDOR_CT);
		    	if (Reverse_Serial_Nbr != null){
		    		map.put("Reverse_Serial_Nbr", new AVP_UTF8String(Reverse_Serial_Nbr).queryValue());
		    	}
		    	// 返销时间
		    	AVP Reverse_Date = avpReverseInformation.find(80157,Constants.DIAMETER_VENDOR_CT);
		    	if (Reverse_Date != null){
		    		map.put("Reverse_Date", new String(new AVP_Time(Reverse_Date).queryValue()));
		    	}
		    	// 本地网区号
		    	AVP Latn_Id = avpReverseInformation.find(80411,Constants.DIAMETER_VENDOR_CT);
		    	if (Latn_Id != null){
		    		map.put("Latn_Id", new AVP_UTF8String(Latn_Id).queryValue());
		    	}
		    }
		} catch (InvalidAVPLengthException e) {
			map = null;
			_log.error(" getAvpsFromMessage is error when Ne response cca message");
		}
		return map;
	}
	
}
